#include "ClipBrushState.h"
#include "BoxTweaker.h"
#include "Command.h"
#include "GeneralEdit.h"
#include "Windows/GxWinApp.h"
#include "MoveState.h"
#include "Editor.h"

namespace FinalRendering
{
	namespace Editor
	{

		class ClipBrushCommand : public Command
		{
		public:
			Plane plane;
			Array<int> brushes;
			Array<RefPtr<Command>> commands;
		public:
			void PerformAction(Scene * Doc)
			{
				commands.Clear();
				RefPtr<DeleteObjectCommand > cmdDelete = new DeleteObjectCommand();
				commands.Add(cmdDelete);
				//int lstID = Doc->Brushes.Count();
				for (int i=0; i<brushes.Count(); i++)
				{
					RefPtr<Brush> bNeg, bPos;
					bNeg = new Brush();
					bPos = new Brush();
					int negID,posID;
					Brush::SplitBrush(plane,*Doc->Brushes[brushes[i]],*bNeg,*bPos,negID,posID);
					if (bNeg->Polygons.Count()>3)
					{
						bNeg->ReCalcPolygonTexcoordSystem();
						bNeg->GeneratePolygonTexcoord();
						AddBrushCommand * cmd = new AddBrushCommand();
						cmd->brush = bNeg;
						bNeg->ReCalcBBox();
						commands.Add(cmd);
					}
					if (bPos->Polygons.Count()>3)
					{
						bPos->ReCalcPolygonTexcoordSystem();
						bPos->GeneratePolygonTexcoord();
						AddBrushCommand * cmd = new AddBrushCommand();
						cmd->brush = bPos;
						bPos->ReCalcBBox();
						commands.Add(cmd);
					}
					cmdDelete->brushID.Add(brushes[i]);
						
				}
				//for (int i=lstID;i<Doc->Brushes.Count();i++)
				//	Doc->Brushes[i]->Selected = true;
				
				
				for (int i=0; i<commands.Count(); i++)
					commands[i]->PerformAction(Doc);

				Doc->Modified = true;
				WorldEditor->SelectionChanged();
				WorldEditor->UpdateViews();
			}

			void UndoAction(Scene * scene)
			{
				for (int i=commands.Count()-1; i>=0; i--)
					commands[i]->UndoAction(scene);
				scene->Modified = true;
				WorldEditor->SelectionChanged();
				WorldEditor->UpdateViews();
			}

		};

		ClipBrushState::ClipBrushState()
		{

		}

		void ClipBrushState::DrawState_3DView(FinalRendering::Editor::View3D *view)
		{
			DrawStates(view);
		}
		
		void ClipBrushState::DrawState_LeftView(FinalRendering::Editor::ViewLeft *view)
		{
			DrawStates(view);
		}

		void ClipBrushState::DrawState_TopView(FinalRendering::Editor::ViewTop *view)
		{
			DrawStates(view);
		}

		void ClipBrushState::DrawState_FrontView(FinalRendering::Editor::ViewFront *view)
		{
			DrawStates(view);
		}

		void ClipBrushState::MouseDown(View * view, UIMouseEventArgs & e)
		{
			
			if ((e.Shift & SS_BUTTONMIDDLE))
			{
				WorldEditor->PushState(new MoveState((View *)view, e.X, e.Y, true));
				return;
			}
			
			State::MouseDown(view,e);
			lstView = view->Type;
			
			view->Refresh();
		}

		void ClipBrushState::UpdatePlane(View * View, int x, int y)
		{
			vec3 WorkPoint;
			View->GetWorldPosFromCursor(ldPosX,ldPosY,WorkPoint,v1);
			View->GetWorldPosFromCursor(x,y,WorkPoint,v2);
			SnapToGrid(View->GridSize,v1);
			SnapToGrid(View->GridSize,v2);
			ov1 = v1;
			ov2 = v2;
			v3 = v2;
			v4 = v1;
			switch(View->Type)
			{
			case View::vtLeft:
				v1.x = -32768.0f;
				v2.x = -32768.0f;
				v3.x = 32768.0f;
				v4.x = 32768.0f;
				break;
			case View::vtTop:
				v1.y = -32768.0f;
				v2.y = -32768.0f;
				v3.y = 32768.0f;
				v4.y = 32768.0f;
				break;
			case View::vtFront:
				v1.z = -32768.0f;
				v2.z = -32768.0f;
				v3.z = 32768.0f;
				v4.z = 32768.0f;
				break;
			}
			PlaneFromVertices(plane,v1,v2,v3);
			v1 -= (v2-v1)*2000.0f;
			v2 += (v2-v1);
			v3 -= (v4-v3)*2000.0f;
			v4 += (v4-v3);

		}

		void ClipBrushState::MouseMove(View *View, UIMouseEventArgs &e)
		{
			UpdateMousePosition(e.X,e.Y);
			if (MouseDragging)
				UpdatePlane(View,e.X,e.Y);
			View->RefreshAllViews();
		}

		void ClipBrushState::MouseUp(View *View, UIMouseEventArgs &e)
		{
			State::MouseUp(View,e);
			
			View->RefreshAllViews();
		}

		void ClipBrushState::DrawStates(View *View)
		{
			if (View->Type == View::vtPerspective)
			{
				glPushAttrib(GL_ENABLE_BIT);
				glEnable(GL_BLEND);
				glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
				glColor4ub(255,200,127,128);
				glDisable(GL_CULL_FACE);
				glBegin(GL_QUADS);
					glVertex3fv((float *)&v1);
					glVertex3fv((float *)&v2);
					glVertex3fv((float *)&v3);
					glVertex3fv((float *)&v4);
				glEnd();
				glPopAttrib();
			}
			else if (View->Type == lstView)
			{
				glColor4ub(255,200,127,255);
				glBegin(GL_LINES);
					glVertex3fv((float *)&v1);
					glVertex3fv((float *)&v2);
				glEnd();
				ControlPoint p;
				p.Position[View->Type] = ov1;
				p.Draw(View);
				p.Position[View->Type] = ov2;
				p.Draw(View);
			}
			
		}

		void ClipBrushState::KeyDown(View * view, UIKeyEventArgs & e)
		{
			if (e.Key != VK_RETURN)
				return;
			if (ov1 == ov2)
				return;
			ClipBrushCommand * cmd = new ClipBrushCommand();
			cmd->plane = plane;
			for (int i=0; i<WorldEditor->Selection.Count(); i++)
			{
				if (WorldEditor->Selection[i].Type == Selection::otBrush)
				{
					cmd->brushes.Add(WorldEditor->Selection[i].ID);
				}
			}
			WorldEditor->Execute(cmd);
			WorldEditor->SelectionChanged();
			GxWinSystem::Debug::WriteLine(L"Shit");
		}

	}
}